import java.io.*;
import java.util.*;

class ParserException extends Exception
{
   ParserException(String s)
   {
      super(s);
   }
}

class RuntimeException extends Exception
{
   RuntimeException(String s)
   {
      super(s);
   }
}

class Class
{
   String name;
   
   Class(String name)
   {
      this.name = name;
   }
   
   public String toString()
   {
      return "class: " + name;
   }

   public String getName()
   {
      return name;
   }
}

class ClassTable extends HashMap<String, Class>
{
   public void add(Class c) throws RuntimeException
   {
      if (containsKey(c.getName()))
         throw new RuntimeException("class '" + c.getName() + "' already added");
      
      put(c.getName(), c);
   }

   public Class get(String name) throws RuntimeException
   {
      if (!containsKey(name))
         throw new RuntimeException("no such class in table");
      return super.get(name);
   }
}

class Var
{
   String name;
   String className;
   
   Var(String name, String className)
   {
      this.name = name;
      this.className = className;
   }
   
   public String getName()
   {
      return name;
   }

   public String getClassName()
   {
      return className;
   }

   public String toString()
   {
      return className + "." + name;
   }
}

class VarTable extends HashMap<String, Var>
{
   public void add(Var v) throws RuntimeException
   {
      if (containsKey(v.getName()))
         throw new RuntimeException("variable '" + v.getName() + "' already added");
      
      put(v.getName(), v);
   }

   public Var get(String name) throws RuntimeException
   {
      if (!containsKey(name))
         throw new RuntimeException("no such variable in table");
      return super.get(name);
   }
}

public class Interpreter
{
   Interpreter(String fileName) throws FileNotFoundException
   {
      System.out.println("-----------------------\nImage file: " + fileName);
      scanner = new Scanner(new FileInputStream(fileName));
   }

   void interpret() throws ParserException
   {
      if (!scanner.next().equals("\"Infanttalk\""))
         throw new ParserException("Not a Infanttalk image");

      // Parse class definitions
      System.out.println("------- Classes");

      String keyword = scanner.next();
      while (keyword.equals("class"))
      {
         loadClass();
         keyword = scanner.next();
      }

      // Similarly for var definitions
      System.out.println("------- Vars");
      while (keyword.equals("var"))
      {
         loadVar();
         if (!scanner.hasNext())
            throw new ParserException("Expected 'end', found end of source");
         keyword = scanner.next();
      }

      if (!keyword.equals("end"))
         throw new ParserException("Expected 'end', found '" + keyword + "'");

      if (scanner.hasNext())
         throw new ParserException("Expected end of source, found '" + scanner.next() + "'");
         
      System.out.println("-----------------------");
   }

   void loadClass() throws ParserException
   {
      String name = scanner.next();
      System.out.println("- " + name);
   }

   void loadVar() throws ParserException
   {
      String name = scanner.next();
      String separator = scanner.next();
      if (!separator.equals(":"))
         throw new ParserException("Missing ':' after 'var " + name + "' clause");

      String type = scanner.next();
      System.out.println("- " + name + "(" + type + ")");
   }

   Scanner scanner;
}
